package uk.co.q3c.deplan.server.util.rules;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.Id;

import uk.co.q3c.deplan.client.domain.AbstractDomainObject;
import uk.co.q3c.deplan.client.domain.DomainKind;
import uk.co.q3c.deplan.client.domain.DomainObject;
import uk.co.q3c.deplan.client.domain.resource.PersistenceReferenceException;
import uk.co.q3c.deplan.client.service.ServiceFactory;
import uk.co.q3c.deplan.server.util.ReflectionFieldType;

import com.googlecode.objectify.Key;

/**
 * Formats and parses text content to and from controls. Formats can be specified at object level (so for example all integers are displayed
 * the same way), or these object rules can be overruled by formats specified at individual property level. If neither is defined, then
 * defaults are used.
 * 
 * @author DSowerby 6 May 2009
 * 
 */
public class PropertyFormatter extends AbstractDomainObject implements Serializable {

	private static final long serialVersionUID = 1L;
	@Id
	private Long keyId;
	private Map<String, String> propertyPatterns;
	private static final String DEFAULT_INTEGER_PATTERN = "#";
	private static final String DEFAULT_DOUBLE_PATTERN = "#.##";
	private static final String DEFAULT_DATE_PATTERN = "KK";
	private String integerPattern;
	private String doublePattern;
	private String datePattern;

	public PropertyFormatter() {
	}

	public String getFormatPattern(String propertyName, ReflectionFieldType type) {

		String pattern = null;
		if (propertyPatterns != null) {
			pattern = propertyPatterns.get(propertyName);
		}
		if (pattern == null) {
			return objectPattern(type);
		} else
			return pattern;
	}

	private String objectPattern(ReflectionFieldType type) {
		String pattern = null;
		switch (type) {
		case INT:
		case SHORT:
		case LONG:
			pattern = integerPattern == null ? DEFAULT_INTEGER_PATTERN : integerPattern;
			break;
		case FLOAT:
		case DOUBLE:
			pattern = doublePattern == null ? DEFAULT_DOUBLE_PATTERN : doublePattern;
			break;
		case DATE:
			pattern = datePattern == null ? DEFAULT_DATE_PATTERN : datePattern;
			break;
		}// switch
		return pattern;
	}

	@Override
	protected void beforeLoad() {
		super.beforeLoad();
		if (propertyPatterns == null) {
			propertyPatterns = new HashMap<String, String>();
		}

	}

	public void setPattern(String propertyName, String pattern) {

		if (propertyPatterns.containsKey(propertyName)) {
			propertyPatterns.remove(propertyName);
		}
		propertyPatterns.put(propertyName, pattern);

	}

	public void clear() {

		propertyPatterns.clear();
	}

	@Override
	public void afterLoad(ServiceFactory connection) {
		super.afterLoad(connection);
	}

	@Override
	public DomainKind getKind() {
		return DomainKind.General;
	}

	public Long getKeyId() {
		return keyId;
	}

	@Override
	public Key<? extends DomainObject> getKey() throws PersistenceReferenceException {
		throw new RuntimeException("Not yet implemented");
	}

	@Override
	public void setKeyId(Long keyId) {
		throw new RuntimeException("Not yet implemented");
	}
}
